﻿using System.ComponentModel;
using System.Windows;
using System.Windows.Markup;

namespace Geometry
{
    public sealed class Line : GObjectBase, IGLine
    {
        public Line()
        {
        }

        public Line(IGPoint _point1, IGPoint _point2)
        {
            this.ConnectPoint1 = _point1;
            this.ConnectPoint2 = _point2;
        }

        protected override void ReleaseDependencies()
        {
            this.ConnectPoint1 = null;
            this.ConnectPoint2 = null;
        }

        protected override void UpdateBoundingBox()
        {
        }

        private IGPoint m_ConnectPoint1;
        public IGPoint ConnectPoint1
        {
            get
            {
                return m_ConnectPoint1;
            }
            set
            {
                if (m_ConnectPoint1 == value) return;

                if (m_ConnectPoint1 != null) m_ConnectPoint1.PropertyChanged -= new PropertyChangedEventHandler(_related_PropertyChanged);
                m_ConnectPoint1 = value;
                if (m_ConnectPoint1 != null) m_ConnectPoint1.PropertyChanged += new PropertyChangedEventHandler(_related_PropertyChanged);

                RaisePropertyChanged("ConnectPoint1");
                RaisePropertyChanged("Point1");
                UpdateCalculations();
            }
        }

        private IGPoint m_ConnectPoint2;
        public IGPoint ConnectPoint2
        {
            get
            {
                return m_ConnectPoint2;
            }
            set
            {
                if (m_ConnectPoint2 == value) return;

                if (m_ConnectPoint2 != null) m_ConnectPoint2.PropertyChanged -= new PropertyChangedEventHandler(_related_PropertyChanged);
                m_ConnectPoint2 = value;
                if (m_ConnectPoint2 != null) m_ConnectPoint2.PropertyChanged += new PropertyChangedEventHandler(_related_PropertyChanged);

                RaisePropertyChanged("ConnectPoint2");
                RaisePropertyChanged("Point2");
                UpdateCalculations();
            }
        }

        private double m_Slope;
        public double Slope
        {
            get
            {
                return m_Slope;
            }
            private set
            {
                // TODO:    following comment is a workaround for a bug, 
                //          whereintersection point doesn't change if line changes but intersection is constant
                // if (m_Slope == value) return;
                m_Slope = value;
                RaisePropertyChanged("Slope");
            }
        }

        

        void _related_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName != "Position") return;

            UpdateCalculations();
        }

        private void UpdateCalculations()
        {
            if (m_ConnectPoint1.IsNull() || m_ConnectPoint2.IsNull()) return;

            this.Slope = ((Point2.Y - Point1.Y) / (Point2.X - Point1.X));
            RaisePropertyChanged("Point1");
            RaisePropertyChanged("Point2");
        }

        #region IGLine Members


        public Point Point1
        {
            get { return m_ConnectPoint1.Position; }
        }

        public Point Point2
        {
            get { return m_ConnectPoint2.Position; }
        }

        #endregion
    }
}
